﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//Для клиента
using MillsClient;
//Для пароля
using System.Security.Cryptography;

namespace ClientMainWindow
{
    public partial class MillsAuthForm : Form
    {
        AsynchronoiusIOClient _millsClientObj = null;
        string recieveMessage = string.Empty;
        string AccountName = string.Empty;
        string AccountPassword = string.Empty;
        
        System.Threading.Thread _recievingThread;

        public MillsAuthForm()
        {
            InitializeComponent();
        }
        public MillsAuthForm(ref AsynchronoiusIOClient client)
        {
            InitializeComponent();
            _millsClientObj = client;
            this.Size = new Size(300, 300);
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            if(_recievingThread != null)
                _recievingThread.Abort();
            
            this.Dispose();
            this.Close();            
        }

        //MD5 шифрование
        private string GetHashString(string pass)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(pass);
            //создаем объект для получения средств шифрования  
            MD5CryptoServiceProvider CSP =
                new MD5CryptoServiceProvider();
            //вычисляем хеш-представление в байтах  
            byte[] byteHash = CSP.ComputeHash(bytes);

            string hash = string.Empty;
            //формируем одну цельную строку из массива  
            foreach (byte b in byteHash)
                hash += string.Format("{0:x2}", b);

            return hash;  
        }

        private void btnAuth_Click(object sender, EventArgs e)
        {
            this.Size = new Size(600, 300);
            gbRegistration.Visible = false;
        }

        private void btnEnterAuth_Click(object sender, EventArgs e)
        {
            if (tbNameAuth.TextLength != 0 && tbPasswordAuth.TextLength != 0)
            {
                AccountName = tbNameAuth.Text;
                AccountPassword = GetHashString(tbPasswordAuth.Text);
                //String message = "auth login=" + AccountName +
                //    " password=" + AccountPassword +@"\EOM";

                String message = "auth " + AccountName +
                    " " + AccountPassword + @"\EOM";

                _millsClientObj.Send(message);
                Logger.WriteLog(string.Format("Send: {0}", message));
                StartRecievingThread(_recievingThread);
            }
        }

        private void btnSendRegistrtion_Click(object sender, EventArgs e)
        {
            if (tbNameReg.TextLength != 0 && tbPassReg1.TextLength != 0 && tbPassReg2.TextLength != 0)
            {
                //Проверяем совпадает ли введенные пароли.
                if (tbPassReg1.Text == tbPassReg2.Text) //Если да - спрашиваем у сервака можем ли региться.
                {
                    AccountPassword = GetHashString(tbPassReg1.Text);
                    AccountName = tbNameReg.Text;
                    //String message = "register login=" + AccountName +
                    //    " password=" + AccountPassword + @"\EOM";

                    String message = "register " + AccountName +
                        " " + AccountPassword + @"\EOM";

                    _millsClientObj.Send(message);
                    Logger.WriteLog(string.Format("Send: {0}", message));

                    StartRecievingThread(_recievingThread);
                }
                else //Если нет - ругаемся на пользователя.
                    MessageBox.Show("Пароль и его подтверждение не совпадают!!\nПроверьте ввод");
            }
        }

        private void StartRecievingThread(System.Threading.Thread thread)
        {
            if (thread != null)
            {
                thread.Abort();
            }
            thread = new System.Threading.Thread(MessageRecieving);
            thread.IsBackground = true;
            thread.Start();
        }

        //Делегат, чтобы делать невидимой ГрупЬокс регистрации. И функция для этого.
        delegate void gbRegDelegate(Object sender);
        private void gbReg(Object sender)
        {
            if (gbRegistration.InvokeRequired)
            {
                gbRegistration.Invoke(new gbRegDelegate(gbReg), new object[] { sender });
                return;
            }
            else
                gbRegistration.Visible = false;
        }

        delegate void newForm();
        void newF()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new newForm(newF), new object[] { });
                return;
            }
            else
            {
                MillsBeforeGameForm mbgf = new MillsBeforeGameForm(ref _millsClientObj, AccountName);
                this.Visible = false;
                DialogResult result = mbgf.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.Cancel)
                {
                    this.Visible = true;
                    tbNameAuth.Text = string.Empty;
                    tbNameReg.Text = string.Empty;
                    tbPasswordAuth.Text = string.Empty;
                    tbPassReg1.Text = string.Empty;
                    tbPassReg2.Text = string.Empty;
                }
                else
                {
                    this.Visible = true;
                    this.Dispose();
                }
            }
        }

        private bool MessageParsing(string message)
        {
            bool flag = true;
            switch (recieveMessage)
            {
                case @"success\EOM":
                    if (gbRegistration.Visible)
                    {
                        gbReg(gbRegistration);
                    }
                    else
                    {
                        newF();
                        //MillsBeforeGameForm mbgf = new MillsBeforeGameForm(ref _millsClientObj, AccountName);
                        //mbgf.ShowDialog();
                        //this.Visible = false;
                    }
                    //flag = true;
                    break;
                case @"denied\EOM":
                    if (gbRegistration.Visible)
                    {
                        MessageBox.Show("Данное имя занято, попробуйте ещё раз");
                    }
                    else
                    {
                        MessageBox.Show("Данные введены не верно\nПовторите ввод!");
                    }
                    //flag = true;
                    break;
                default:
                    flag = false;
                    break;        
            }
            return flag;
        }

        private void MessageRecieving()
        {
            while (true)
            {
                recieveMessage = _millsClientObj.ConnectionInformation.recieveBuffer;
                if (recieveMessage != string.Empty)
                {
                    Logger.WriteLog(string.Format("Rec: {0}", recieveMessage));
                    if (MessageParsing(recieveMessage))
                    {
                        //_recievingThread.Abort();
                        break; }
                    recieveMessage = string.Empty;
                    _millsClientObj.ConnectionInformation.recieveBuffer = string.Empty;
                    System.Threading.Thread.Sleep(1000);
                }
            }
        }

        private void btnRegistration_Click(object sender, EventArgs e)
        {
            this.Size = new Size(600, 300);
            gbRegistration.Visible = true;
        }

        private void MillsAuthForm_Load(object sender, EventArgs e)
        {
            _millsClientObj.Recieve();
            tssMessage.Text = Encoding.ASCII.GetString(_millsClientObj.ConnectionInformation.Buffer);
        }

        private void btnAbout_Click(object sender, EventArgs e)
        {
            FormAbout fa = new FormAbout();
            fa.Show();
        }

        private void MillsAuthForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            _millsClientObj.CloseConnection();
            this.Dispose();
        }
    }
}
